package com.lxl.bt.util;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.lxl.bt.BuildConfig;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @Author : xinlong.lv
 */
public class MapUtil {

    private static final String TAG = MapUtil.class.getSimpleName();

    // 百度地图包名
    public static final String PN_BAIDU_MAP = "com.baidu.BaiduMap";
    // 高德地图包名
    public static final String PN_GAODE_MAP = "com.autonavi.minimap";
    // 腾讯地图包名
    public static final String PN_TENCENT_MAP = "com.tencent.map";

    /**
     * 检查地图应用是否安装
     *
     * @return
     */
    public static boolean isGdMapInstalled() {
        return isInstallPackage(PN_GAODE_MAP);
    }

    public static boolean isBaiduMapInstalled() {
        return isInstallPackage(PN_BAIDU_MAP);
    }

    public static boolean isTencentMapInstalled() {
        return isInstallPackage(PN_TENCENT_MAP);
    }

    private static boolean isInstallPackage(String packageName) {
        File folderFile = new File("/data/data/" + packageName);
        Log.e(TAG, "isInstallPackage: FilePath=" + folderFile.getAbsolutePath());
        Log.e(TAG, "isInstallPackage: exists===" + folderFile.exists());
        Log.e(TAG, "isInstallPackage: length===" + folderFile.length());
        Log.e(TAG, "isInstallPackage: length===" + folderFile.isDirectory());
        return folderFile.exists();
    }

    /**
     * 根据所给包名判断当前App是否已经安装 （方法2）
     *
     * @param context
     * @param packageName 要判断的是否安装的应用包名
     * @return
     * @see #isAppHasInstalled
     */
    @Deprecated
    public static boolean isAppInstalled(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();
        List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0);
        for (PackageInfo packageInfo : packageInfoList) {
            if (packageName.equals(packageInfo.packageName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根据所给包名判断当前App是否已经安装 （方法1）
     *
     * @param context
     * @param packageName 要判断的是否安装的应用包名
     * @return
     */
    public static boolean isAppHasInstalled(Context context, String packageName) {
        PackageInfo packageInfo;
        try {
            packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            packageInfo = null;
            e.printStackTrace();
        }
        return (packageInfo != null);
    }


    /**
     * 获取地图个性化json文件的路径
     */
    public static String getMapStyleFilePath(Context context, String styleFileName) {
        FileOutputStream outputStream = null;
        InputStream inputStream = null;
        String parentPath = null;
        try {
            inputStream = context.getAssets().open("customConfigdir/" + styleFileName);
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);
            parentPath = context.getFilesDir().getAbsolutePath();
            File customStyleFile = new File(parentPath + "/" + styleFileName);
            if (customStyleFile.exists()) {
                customStyleFile.delete();
            }
            customStyleFile.createNewFile();

            outputStream = new FileOutputStream(customStyleFile);
            outputStream.write(buffer);
        } catch (IOException e) {
            Log.e(TAG, "Copy custom style file failed", e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                Log.e(TAG, "Close stream failed", e);
                return null;
            }
        }
        return parentPath + "/" + styleFileName;
    }

    /**
     * 高德、腾讯转百度
     *
     * @param gd_lon
     * @param gd_lat
     * @return
     */
    private static double[] gaoDeToBaidu(double gd_lon, double gd_lat) {
        double[] bd_lat_lon = new double[2];
        double PI = 3.14159265358979324 * 3000.0 / 180.0;
        double x = gd_lon, y = gd_lat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * PI);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * PI);
        bd_lat_lon[0] = z * Math.cos(theta) + 0.0065;
        bd_lat_lon[1] = z * Math.sin(theta) + 0.006;
        return bd_lat_lon;
    }

    /**
     * 打开高德地图导航功能
     *
     * @param context
     * @param slat    起点纬度
     * @param slon    起点经度
     * @param sname   起点名称 可不填（0,0，null）
     * @param dlat    终点纬度
     * @param dlon    终点经度
     * @param dname   终点名称 必填
     */
    public static void openGaoDeNavi(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
        String uriString = null;
        StringBuilder builder = new StringBuilder("amapuri://route/plan?sourceApplication=lanchuang");
        if (slat != 0) {
            builder.append("&sname=").append(sname)
                    .append("&slat=").append(slat)
                    .append("&slon=").append(slon);
        }
        builder.append("&dlat=").append(dlat)
                .append("&dlon=").append(dlon)
                .append("&dname=").append(dname)
                .append("&dev=0")
                .append("&t=0");
        uriString = builder.toString();
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setPackage(PN_GAODE_MAP);
        intent.setData(Uri.parse(uriString));
        context.startActivity(intent);
    }

    /**
     * 打开腾讯地图
     * params 参考http://lbs.qq.com/uri_v1/guide-route.html
     *
     * @param context
     * @param slat    起点纬度
     * @param slon    起点经度
     * @param sname   起点名称 可不填（0,0，null）
     * @param dlat    终点纬度
     * @param dlon    终点经度
     * @param dname   终点名称 必填
     *                驾车：type=drive，policy有以下取值
     *                0：较快捷
     *                1：无高速
     *                2：距离
     *                policy的取值缺省为0
     *                &from=" + dqAddress + "&fromcoord=" + dqLatitude + "," + dqLongitude + "
     */
    public static void openTencentMap(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
        String uriString = null;
        StringBuilder builder = new StringBuilder("qqmap://map/routeplan?type=drive&policy=0&referer=zhongshuo");
        if (slat != 0) {
            builder.append("&from=").append(sname)
                    .append("&fromcoord=").append(slat)
                    .append(",")
                    .append(slon);
        }
        builder.append("&to=").append(dname)
                .append("&tocoord=").append(dlat)
                .append(",")
                .append(dlon);
        uriString = builder.toString();
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setPackage(PN_TENCENT_MAP);
        intent.setData(Uri.parse(uriString));
        context.startActivity(intent);
    }


    /**
     * 打开百度地图路线规划（导航）功能
     *
     * @param context        上下文
     * @param destinationLat 目的地纬度
     * @param destinationLng 目的地经度
     * @param coord_type     坐标类型  允许的值为bd09ll、bd09mc、gcj02、wgs84。
     *                       bd09ll表示百度经纬度坐标，bd09mc表示百度墨卡托坐标，gcj02表示经过国测局加密的坐标，wgs84表示gps获取的坐标
     * @param mode           导航类型导航模式：可选transit（公交）、 driving（驾车）、 walking（步行）和riding（骑行）.
     * @param src            必选参数，格式为：android.companyName.appName 不传此参数，不保证服务
     * @see @http://lbsyun.baidu.com/index.php?title=uri/api/android  （2.3.2 路线规划）
     */
    public void startBaiduNavigate(Context context, String destinationLat, String destinationLng, String coord_type, String mode, String src) {
        Intent intent = new Intent();
        intent.setData(Uri.parse("baidumap://map/direction?destination=" +
                destinationLat + "," + destinationLng + "&coord_type=" + coord_type +
                "&mode=" + mode + "&src=" + src + "#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end"));
        context.startActivity(intent);
    }

    /**
     * 打开百度地图路线规划（导航）功能
     *
     * @param context 上下文
     * @param sLat    起点纬度
     * @param sLon    起点经度
     * @param sName   起点名称 可不填（0, 0, null）
     * @param dLat    终点纬度
     * @param dLon    终点经度
     * @param dName   终点名称 必填
     * @see @http://lbsyun.baidu.com/index.php?title=uri/api/android （2.3.2 路线规划）
     */
    public static void openBaiDuNavigate(Context context, double sLat, double sLon, String sName,
                                         String dLat, String dLon, String dName) {

        StringBuilder builder = new StringBuilder("baidumap://map/direction?coord_type=bd09ll&mode=driving");
        if (sLat != 0 && sLat != 0) {
            builder.append("&origin=latlng:").append(sLat).append(",").append(sLon)
                    .append("|name:").append(sName);
        }

        builder.append("&destination=latlng:").append(dLat).append(",").append(dLon)
                .append("|name:").append(TextUtils.isEmpty(dName) ? "终点" : dName);

        builder.append("&src=").append(BuildConfig.APPLICATION_ID);

        Log.e(TAG, "openBaiDuNavigate: builder.toString()======" + builder.toString());
        Intent intent = new Intent(Intent.ACTION_VIEW);
//        intent.setPackage(BuildConfig.APPLICATION_ID);
        intent.setData(Uri.parse(builder.toString()));
        context.startActivity(intent);
    }
    /**
     * 地球半径，单位：公里/千米
     */
    private static final double EARTH_RADIUS = 6378.137;

    /**
     * 经纬度转化成弧度
     * @param d  经度/纬度
     * @return  经纬度转化成的弧度
     */
    private static double radian(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 返回两个地理坐标之间的距离
     * @param firsLongitude 第一个坐标的经度
     * @param firstLatitude 第一个坐标的纬度
     * @param secondLongitude 第二个坐标的经度
     * @param secondLatitude  第二个坐标的纬度
     * @return 两个坐标之间的距离，单位：公里/千米
     */
    public static double distance(double firstLatitude,double firsLongitude, double secondLatitude,
                                  double secondLongitude ) {
        double firstRadianLongitude = radian(firsLongitude);
        double firstRadianLatitude = radian(firstLatitude);
        double secondRadianLongitude = radian(secondLongitude);
        double secondRadianLatitude = radian(secondLatitude);

        double a = firstRadianLatitude - secondRadianLatitude;
        double b = firstRadianLongitude - secondRadianLongitude;
        double cal = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(firstRadianLatitude) * Math.cos(secondRadianLatitude)
                * Math.pow(Math.sin(b / 2), 2)));
        cal = cal * EARTH_RADIUS;

        return Math.round(cal * 10000d) / 10000d;
    }

    /**
     * 返回两个地理坐标之间的距离
     * @param firstPoint 第一个坐标 例如："23.100919, 113.279868"
     * @param secondPoint 第二个坐标 例如："23.149286, 113.347584"
     * @return 两个坐标之间的距离，单位：公里/千米
     */
    public static double distance(String firstPoint, String secondPoint){
        String[] firstArray = firstPoint.split(",");
        String[] secondArray = secondPoint.split(",");
        double firstLatitude = Double.valueOf(firstArray[0].trim());
        double firstLongitude = Double.valueOf(firstArray[1].trim());
        double secondLatitude = Double.valueOf(secondArray[0].trim());
        double secondLongitude = Double.valueOf(secondArray[1].trim());
        return distance(firstLatitude, firstLongitude, secondLatitude, secondLongitude);
    }


}
